<?php namespace System;

class Model
{

    public $db;
    public $error;
    protected $table;
    protected $fields;
    protected $deleted = false;
    protected $id = 'id';
    protected $insertId;

    public function __construct()
    {
        $config = new \System\Config();
        if ($config->db) {
            $config->load('Database');
            $this->db = new \System\Db($config->mysql);
        } else {
            showError('No database settings');
        }
    }

    public function select($select = '*')
    {
        $this->db->select($select);
        return $this;
    }

    public function where($key, $val = '', $operator = null, $or = false, $likeLR = 'both')
    {
        $this->db->where($key, $val, $operator, $or, $likeLR);
        return $this;
    }

    public function order($by, $sort = 'ASC')
    {
        $this->db->order($by, $sort);
        return $this;
    }

    public function like($name, $value, $likeLR = "both")
    {
        $this->db->where($name, $value, "like", false, $likeLR);
        return $this;
    }

    public function join($table, $on, $type = 'left')
    {
        $this->db->join($table, $on, $type);
        return $this;
    }

    public function set($key, $val = null)
    {
        $this->db->set($key, $val);
        return $this;
    }

    public function limit($limit, $offset = null)
    {
        $this->db->limit($limit, $offset);
        return $this;
    }

    public function update($data = null, $where = null)
    {
        $this->db->update($this->table, $data, $where);
    }

    public function get($where = '')
    {
        if ($where) {
            $this->db->where($where);
        }
        return $this->db->get($this->table)->result();
    }

    public function first($where = '')
    {
        if ($where) {
            $this->db->where($where);
        }
        return $this->db->get($this->table)->first();
    }

    public function find($id = '')
    {
        $this->db->table($this->table);
        if ($id) {
            return $this->db->where($this->id, $id)->get()->first();
        } else {
            return $this->db->get()->result();
        }
    }

    public function count()
    {
        return $this->db->count();
    }

    public function countAll($where = null)
    {
        return $this->db->countAll($this->table, $where);
    }

    public function findAll($limit = null, $offset = 0)
    {
        if ($limit) {
            $this->db->limit($limit, $offset);
        }
        return $this->db->get($this->table)->result();
    }

    public function json()
    {
        return json_encode($this->db->get($this->table)->result());
    }

    public function datatable($totalName = "total", $rowsName = "rows", $json = true)
    {
        $total = $this->db->countAll($this->table, '', false);
        $rows = $this->db->get($this->table)->result();
        return $json ? json_encode([$totalName => $total, $rowsName => $rows]) : [$totalName => $total, $rowsName => $rows];
    }

    public function save($data)
    {
        if (isset($data[$this->id]) && $data[$this->id] != 0) {
            $id = $data[$this->id];
            unset($data[$this->id]);
            $this->db->update($this->table, $data, [$this->id => $id]);
        } else {
            $this->insertId = $this->db->insert($this->table, $data);
        }
    }

    public function insertId()
    {
        return $this->insertId;
    }

    public function lastQuery()
    {
        return $this->db->lastQuery();
    }

    public function delete($id = '')
    {
        if ($id) {
            $this->db->reset();
            $this->db->where($this->id, $id);
        }
        if ($this->deleted) {
            $this->db->set('deleted', 1)->update($this->table);
        } else {
            $this->db->delete($this->table);
        }
    }

    public function dbError()
    {
        return $this->db->error;
    }

    public function error()
    {
        return $this->error;
    }
}